﻿using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
/// <summary>
/// 管理Manager，Manager通常和游戏逻辑相关，依靠GameObject和Mono
/// </summary>
public class ManagerService : ILogic
{
    private readonly Dictionary<Type, ManagerBase> managerDic = new Dictionary<Type, ManagerBase>();
    public Transform managerRoot;
    private GameRoot gameRoot;
    public void OnInit()
    {
        gameRoot = GameRoot.Instance;
        if (managerRoot == null)
        {
            var go = new GameObject("ManagerRoot");
            managerRoot = go.transform;
            managerRoot.transform.SetParent(gameRoot.transform);
        }
        else
        {
            for (int i = 0; i < managerRoot.transform.childCount; i++)
            {
                GameObject.Destroy(managerRoot.transform.GetChild(i).gameObject);
            }
        }
    }
    public void OnUpdate()
    {

    }
    public void UnInit()
    {
    }
    public void OnEnterState()
    {

    }
    public void OnExit()
    {
        foreach (var manager in managerDic.Values)
        {
            manager.OnExit();
        }
    }
    //更新Manager 
    public void UpdateManager(GameObject[] newGameManagers)
    {
        if (newGameManagers == null || newGameManagers.Length == 0)
        {
            UnRegisterAllManager();
            return;
        }
        HashSet<Type> targetManagers = new HashSet<Type>();
        foreach (GameObject gameManager in newGameManagers)
        {
            if (gameManager == null)
            {
                continue;
            }
            var manager = gameManager.GetComponent<ManagerBase>();
            if (manager == null)
            {
                continue;
            }
            Type type = manager.GetType();
            //如果已经有了也不会重复注册为
            if (targetManagers.Add(type))//如果为True表示新的Manager，为false表示重复的Manager
            {
                RegisterManager(manager);//添加新的Manager
            }
        }
        HashSet<Type> noUsedManagers = new HashSet<Type>();
        foreach (var managerType in managerDic.Keys)
        {
            if (!targetManagers.Contains(managerType))
            {
                noUsedManagers.Add(managerType);
            }
        }
        foreach (var managerType in noUsedManagers)
        {
            UnRegisterManager(managerType);//移除没有用的Manager
        }
        InitManager();
    }

    private void InitManager()
    {
        foreach (var manager in managerDic.Values.ToList<ManagerBase>())
        {
            manager.OnShow();
        }
    }

    //注册Manager
    private void RegisterManager(ManagerBase manager)
    {
        if (manager == null)
        {
            return;
        }
        if (!managerDic.ContainsKey(manager.GetType()))
        {
            GameObject go = GameObject.Instantiate(manager.gameObject, managerRoot, false);
            var mngComp = go.GetComponent<ManagerBase>();
            managerDic[mngComp.GetType()] = mngComp;//这样添加的对象mngComp才会和场景中的gameject类型相对应

            //这里百分比会注册新的Manager
            mngComp.OnAwake();
        }
    }
    //注销Manager

    private void UnRegisterAllManager()
    {
        HashSet<Type> types = new HashSet<Type>();
        foreach (var manager in managerDic.Values)
        {
            types.Add(manager.GetType());
            
        }
        foreach (var manager in types)
        {
            UnRegisterManager(manager);
        }
    }

    private void UnRegisterManager(ManagerBase managerComp)
    {
        if (managerComp == null)
        {
            return;
        }
        Type type = managerComp.GetType();
        if (managerDic.ContainsKey(type))
        {
            GameObject.Destroy(managerDic[type].gameObject);
            managerDic.Remove(type);
        }
    }
    private void UnRegisterManager(Type type)
    {
        if (type == null) { return; }
        if (managerDic.ContainsKey(type))
        {
            managerDic[type].UnInit();//注销
            GameObject.Destroy(managerDic[type].gameObject);//销毁
            managerDic.Remove(type);
            this.Log("移除：" + type.Name);
        }
    }
    //获取Manager
    public T GetManager<T>() where T : ManagerBase
    {
        Type type = typeof(T);
        if (!managerDic.TryGetValue(type, out var managerBase))
        {
            this.Warn($"type：{type.Name} is null ,maybe init order is error!");
            return null;
        }
        return managerBase as T;
    }
    public bool CheckManager<T>() where T : ManagerBase
    {
        Type type = typeof(T);
        if (!managerDic.TryGetValue(type, out var managerBase))
        {
            return false;
        }
        return true;
    }

  
}